package com.edu.juc.cas.atomic;

import com.edu.juc.bean.Student;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicMarkableReference;
import java.util.concurrent.atomic.AtomicStampedReference;

// 解决ABA问题
public class AtomicStampedDemo {
    public static void main(String[] args) {
        Student Zhangsan = new Student(1, "张三", "软件工程");
        Student lisi = new Student(2, "李四", "软件工程");
        AtomicStampedReference<Student> atomicStampedReference = new AtomicStampedReference<>(Zhangsan, 1);
        System.out.println(atomicStampedReference.compareAndSet(Zhangsan, lisi, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
        System.out.println(atomicStampedReference.compareAndSet(lisi, Zhangsan, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
        System.out.println(atomicStampedReference.compareAndSet(Zhangsan, lisi, 1, 2));

        AtomicMarkableReference<Integer> markableReference = new AtomicMarkableReference<>(100, false);
        new Thread(() -> {
            boolean marked = markableReference.isMarked();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println(markableReference.compareAndSet(100, 200, marked, !marked));
        }, "t1").start();

        new Thread(() -> {
            boolean marked = markableReference.isMarked();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println(markableReference.compareAndSet(100, 200, marked, !marked));
        }, "t2").start();


    }
    /*
     * AtomicStampedReference:原子更新带有时间戳的引用, Version 版本 +1   解决修改过几次问题
     * AtomicMarkableReference:原子更新带有标记的引用, 一次修改， false -> true  解决是否修改过的问题
     */
}
